package org.opens.filemanager.controller;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.opens.filemanager.entity.EditContent;
import org.opens.filemanager.entity.FileItemEntity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;

@RestController
@RequestMapping(value = "/api/file/manager")
@CrossOrigin(origins = "*", maxAge = 3600, allowCredentials = "true")
public class FileManagerController {

    /**
     * 文件管理器目录
     */
    @Value("${filemanager.root}")
    private String root;

    /**
     * 功能:
     *      获取文件列表
     * @param path  root拼接path生成路径
     */
    @GetMapping(value = "/list")
    public JSONObject showFileList(
            @RequestParam(value = "path", required = true) String path
    ) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);

        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(root, path))) {
            List<FileItemEntity> fileList = new ArrayList<>();
            for (Path x : directoryStream) {// 获取文件基本属性
                BasicFileAttributes attrs = Files.readAttributes(x, BasicFileAttributes.class);

                FileItemEntity fileItem = new FileItemEntity();
                fileItem.setName(x.getFileName().toString());
                fileItem.setDate(new Date(attrs.lastModifiedTime().toMillis()));
                fileItem.setSize(attrs.size());
                fileItem.setType(attrs.isDirectory() ? "dir" : "file");

                fileList.add(fileItem);
            }

            jsonObject.put("data", fileList);
            return jsonObject;
        } catch (IOException e) {
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("message", "服务器异常");
        }
        jsonObject.put("data", Collections.emptyList());
        return jsonObject;
    }

    @PostMapping(value = "/folder")
    public JSONObject createFolder(
            @RequestParam(value = "path", required = true) String path,
            @RequestParam(value = "newPath", required = true) String newPath
    ) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);

        Path realPath = Paths.get(root, path, newPath);
        File file = new File(realPath.toString());
        if ( file.exists() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "目录已经存在");
            return jsonObject;
        }

        if ( !file.mkdir() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "目录创建失败");
            return jsonObject;
        }

        jsonObject.put("message", "目录创建成功");
        return jsonObject;
    }

    @DeleteMapping(value = "/folder")
    public JSONObject delFolder(
            @RequestParam(value = "path", required = true) String path,
            @RequestParam(value = "deleteFolderName", required = true) String deleteFolderName
    ) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);

        Path realPath = Paths.get(root, path, deleteFolderName);
        File file = new File(realPath.toString());
        if ( !file.exists() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "目录不存在");
            return jsonObject;
        }

        if ( !file.isDirectory() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "删除对象不是目录");
            return jsonObject;
        }

        File[] files = file.listFiles();
        if ( files != null && files.length > 0 ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "该目录部位空, 无法删除");
            return jsonObject;
        }

        if ( !file.delete() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "删除失败");
            return jsonObject;
        }

        jsonObject.put("message", "目录删除成功");
        return jsonObject;
    }

    @DeleteMapping(value = "/file")
    public JSONObject deleteFile(
            @RequestParam(value = "path", required = true) String path,
            @RequestParam(value = "deleteFileName", required = true) String deleteFileName
    ) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);

        Path realPath = Paths.get(root, path, deleteFileName);
        File file = new File(realPath.toString());
        if ( !file.exists() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "文件不存在");
            return jsonObject;
        }

        if ( !file.isFile() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "删除对象不是文件");
            return jsonObject;
        }

        if ( !file.delete() ) {
            jsonObject.put("code", 300);
            jsonObject.put("message", "删除文件失败");
            return jsonObject;
        }

        jsonObject.put("message", "文件删除成功");
        return jsonObject;
    }

    @GetMapping(value = "/content")
    public JSONObject getContent(
            @RequestParam(value = "path", required = true) String path,
            @RequestParam(value = "fileName", required = true) String fileName
    ) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);

        Path realPath = Paths.get(root, path, fileName);
        File file = new File(realPath.toString());
        try {
            String content = FileUtils.readFileToString(file);
            jsonObject.put("content", content);
        } catch (IOException e) {
            e.printStackTrace();
            jsonObject.put("code", 201);
        }
        return jsonObject;
    }

    @PatchMapping(value = "/edit")
    public JSONObject editFile(
            @RequestBody EditContent editContent
    ) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);

        Path realPath = Paths.get(root, editContent.getPath(), editContent.getFileName());
        File file = new File(realPath.toString());

        try {
            FileUtils.write(file, editContent.getContent());
        } catch (IOException e) {
            e.printStackTrace();
            jsonObject.put("code", 201);
        }

        return jsonObject;
    }

    @PutMapping(value = "/upload")
    public JSONObject upload(
            @RequestParam(value = "path", required = true) String path,
            HttpServletRequest request
    ) {
        try {
            Collection<Part> parts = request.getParts();
            for (Part part : parts) {
                if ( part.getContentType() != null ) {
                    Path realPath = Paths.get(root, path);
                    System.out.println(333 + " " + part.getName());
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String path1 = "/temp/";
        String path2 = "/txt/";
        String path3 = "/area/";
        Path path = Paths.get(path1, path2, path3);
    }

}
